/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.classes.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.modules.classes.entity.ClassesPlanEntity;
import org.springblade.modules.classes.entity.ClassesUserEntity;
import org.springblade.modules.classes.entity.TrainingPlanCourseEntity;
import org.springblade.modules.classes.entity.TrainingPlanEntity;
import org.springblade.modules.classes.excel.TrainingPlanExcel;
import org.springblade.modules.classes.mapper.TrainingPlanMapper;
import org.springblade.modules.classes.service.IClassesPlanService;
import org.springblade.modules.classes.service.IClassesUserService;
import org.springblade.modules.classes.service.ITrainingPlanCourseService;
import org.springblade.modules.classes.service.ITrainingPlanService;
import org.springblade.modules.classes.vo.TrainingPlanVO;
import org.springblade.modules.classes.wrapper.TrainingPlanWrapper;
import org.springblade.modules.course.entity.CourseChapterEntity;
import org.springblade.modules.course.entity.CourseChapterSubEntity;
import org.springblade.modules.course.entity.CourseEntity;
import org.springblade.modules.course.service.ICourseChapterService;
import org.springblade.modules.course.service.ICourseChapterSubService;
import org.springblade.modules.course.service.ICourseService;
import org.springblade.modules.course.vo.CourseVO;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 培训计划表 服务实现类
 *
 * @author junxin
 * @since 2023-04-26
 */
@Service
@AllArgsConstructor
public class TrainingPlanServiceImpl extends BaseServiceImpl<TrainingPlanMapper, TrainingPlanEntity> implements ITrainingPlanService {
	private final ITrainingPlanCourseService trainingPlanCourseService;
	private final ICourseService courseService;
	private final IClassesUserService classesUserService;
	private final IClassesPlanService classesPlanService;
	private final ICourseChapterService courseChapterService;
	private final ICourseChapterSubService courseChapterSubService;

	@Override
	public IPage<TrainingPlanVO> selectTrainingPlanPage(IPage<TrainingPlanVO> page, TrainingPlanVO trainingPlan) {
		return page.setRecords(baseMapper.selectTrainingPlanPage(page, trainingPlan));
	}


	@Override
	public List<TrainingPlanExcel> exportTrainingPlan(Wrapper<TrainingPlanEntity> queryWrapper) {
		List<TrainingPlanExcel> trainingPlanList = baseMapper.exportTrainingPlan(queryWrapper);
		//trainingPlanList.forEach(trainingPlan -> {
		//	trainingPlan.setTypeName(DictCache.getValue(DictEnum.YES_NO, TrainingPlan.getType()));
		//});
		return trainingPlanList;
	}

	@Override
	public List<Long> getUserTrainingPlanIds(Long userId) {
		//查询该用户的所在班级
		List<ClassesUserEntity> classesUserEntitylist = classesUserService.list(Wrappers.<ClassesUserEntity>query().lambda()
			.eq(ClassesUserEntity::getUserId, userId));

		if (CollectionUtil.isEmpty(classesUserEntitylist)) return null;
		//获取该用户的所有的班级id
		List<Long> classesIdsList = classesUserEntitylist.stream().map(ClassesUserEntity::getClassesId).collect(Collectors.toList());

		//获取classesIdsList的所有培训计划ids
		List<ClassesPlanEntity> classesPlanEntitylist = classesPlanService.list(Wrappers.<ClassesPlanEntity>query().lambda()
			.in(ClassesPlanEntity::getClassesId, classesIdsList));
		if (CollectionUtil.isEmpty(classesUserEntitylist)) return null;

		//获得培训计划的所有ids
		return classesPlanEntitylist.stream().map(ClassesPlanEntity::getPlanId).collect(Collectors.toList());
	}

	@Override
	public List<TrainingPlanEntity> getUserTrainingPlan(Long userId) {
		//查询该用户的所在班级
		List<ClassesUserEntity> classesUserEntitylist = classesUserService.list(Wrappers.<ClassesUserEntity>query().lambda()
			.eq(ClassesUserEntity::getUserId, userId));

		if (CollectionUtil.isEmpty(classesUserEntitylist)) R.success("该用户没有设置班级");
		//获取该用户的所有的班级id
		List<Long> classesIdsList = classesUserEntitylist.stream().map(ClassesUserEntity::getClassesId).collect(Collectors.toList());

		//获取classesIdsList的所有培训计划ids
		List<ClassesPlanEntity> classesPlanEntitylist = classesPlanService.list(Wrappers.<ClassesPlanEntity>query().lambda()
			.in(ClassesPlanEntity::getClassesId, classesIdsList));
		if (CollectionUtil.isEmpty(classesUserEntitylist)) R.success("该用户的班级没有对应的培训计划");

		//获得培训计划的所有ids
		List<Long> planIdsList = classesPlanEntitylist.stream().map(ClassesPlanEntity::getPlanId).collect(Collectors.toList());
		return this.listByIds(planIdsList);
	}

	@Override
	public List<TrainingPlanCourseEntity> selectByUserIdAndCourseId(Long userId, Long courseId) {
		return baseMapper.selectByUserIdAndCourseId(userId, courseId);
	}

	@Override
	public List<TrainingPlanVO> trainingPlanDetail(List<Long> trainPlanIds, List<TrainingPlanVO> trainingPlanList) {

		return trainingPlanList.stream().map(trainingPlanEntity -> {
			TrainingPlanVO record = TrainingPlanWrapper.build().entityVO(trainingPlanEntity);
			AtomicInteger planCompleteFlag = new AtomicInteger(0);
			long planId = record.getId();
			record.setTrainingPlanId(planId);
			//获取该培训计划的 培训计划课程 并根据课程节点升序
			List<TrainingPlanCourseEntity> trainingPlanCourseList = trainingPlanCourseService.list(Wrappers.<TrainingPlanCourseEntity>query().lambda()
				.eq(TrainingPlanCourseEntity::getTrainingPlanId, planId).orderByAsc(TrainingPlanCourseEntity::getSort));
			//给每条培训计划设置对应的课程列表值
			if (CollectionUtil.isEmpty(trainingPlanCourseList)) return record;
			record.setCourseList(trainingPlanCourseList.stream().map(trainingPlanCourseEntity -> {
				//课程设置
				CourseEntity courseEntity = courseService.getById(trainingPlanCourseEntity.getCourseId());
				if (planCompleteFlag.get() == 0 && null != courseEntity && null != AuthUtil.getUserId()) {
					boolean flag = courseService.checkCourseComplete(courseEntity.getId(), AuthUtil.getUserId());
					if (!flag) planCompleteFlag.getAndAdd(1);
				}


				CourseVO courseVO = new CourseVO();
				if (null == courseEntity) {
					return courseVO;
				}
				BeanUtil.copyProperties(courseEntity, courseVO);
				courseVO.setIsExam(trainingPlanCourseEntity.getIsExam());
				courseVO.setChapters(courseChapterService.count(Wrappers.<CourseChapterEntity>query().lambda().eq(CourseChapterEntity::getCourseId, trainingPlanCourseEntity.getCourseId())));
				courseVO.setSubs(courseChapterSubService.count(Wrappers.<CourseChapterSubEntity>query().lambda().eq(CourseChapterSubEntity::getCourseId, trainingPlanCourseEntity.getCourseId())));
				return courseVO;
			}).collect(Collectors.toList()));

			if (planCompleteFlag.get() > 0) record.setIsComplete(0);//表示有未完成的课程
			else record.setIsComplete(1);//表示该培训计划所有的课程都已完成
			return record;
		}).collect(Collectors.toList());
	}

}
